package com.campus.lostandfound.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.campus.lostandfound.common.Result;
import com.campus.lostandfound.entity.Announcement;
import com.campus.lostandfound.service.AnnouncementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Redis缓存测试Controller
 * 用于诊断缓存问题
 */
@RestController
@RequestMapping("/cache-test")
@CrossOrigin
public class CacheTestController {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private CacheManager cacheManager;
    
    @Autowired
    private AnnouncementService announcementService;
    
    /**
     * 测试1：检查Redis连接
     */
    @GetMapping("/redis-connection")
    public Result<Map<String, Object>> testRedisConnection() {
        Map<String, Object> result = new HashMap<>();
        try {
            // 测试写入
            redisTemplate.opsForValue().set("test:connection", "Hello Redis!");
            
            // 测试读取
            String value = (String) redisTemplate.opsForValue().get("test:connection");
            
            // 测试删除
            redisTemplate.delete("test:connection");
            
            result.put("status", "SUCCESS");
            result.put("message", "Redis连接正常");
            result.put("testValue", value);
            
            return Result.success("Redis连接测试成功", result);
        } catch (Exception e) {
            result.put("status", "FAILED");
            result.put("error", e.getMessage());
            result.put("stackTrace", e.getClass().getName());
            return Result.error("Redis连接失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试2：查看所有缓存key
     */
    @GetMapping("/cache-keys")
    public Result<Map<String, Object>> getAllCacheKeys() {
        Map<String, Object> result = new HashMap<>();
        try {
            // 获取所有key
            Set<String> allKeys = redisTemplate.keys("*");
            Set<String> announcementKeys = redisTemplate.keys("announcement::*");
            Set<String> userKeys = redisTemplate.keys("user::*");
            
            result.put("totalKeys", allKeys != null ? allKeys.size() : 0);
            result.put("allKeys", allKeys);
            result.put("announcementKeys", announcementKeys);
            result.put("userKeys", userKeys);
            
            return Result.success("缓存key列表", result);
        } catch (Exception e) {
            return Result.error("获取缓存key失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试3：测试公告缓存
     */
    @GetMapping("/announcement-cache")
    public Result<Map<String, Object>> testAnnouncementCache() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            System.out.println("\n========== 开始测试公告缓存 ==========");
            
            // 第一次调用（应该查询数据库）
            long start1 = System.currentTimeMillis();
            IPage<Announcement> page1 = announcementService.getAnnouncementList(1, 10);
            long time1 = System.currentTimeMillis() - start1;
            System.out.println("【测试】第一次查询耗时: " + time1 + "ms");
            
            // 等待100ms确保缓存写入完成
            Thread.sleep(100);
            
            // 检查缓存key是否存在
            Set<String> keys = redisTemplate.keys("announcement::*");
            System.out.println("【测试】缓存key数量: " + (keys != null ? keys.size() : 0));
            if (keys != null && !keys.isEmpty()) {
                System.out.println("【测试】缓存key列表: " + keys);
            }
            
            // 第二次调用（应该从缓存读取）
            long start2 = System.currentTimeMillis();
            IPage<Announcement> page2 = announcementService.getAnnouncementList(1, 10);
            long time2 = System.currentTimeMillis() - start2;
            System.out.println("【测试】第二次查询耗时: " + time2 + "ms");
            
            // 第三次调用（应该从缓存读取）
            long start3 = System.currentTimeMillis();
            IPage<Announcement> page3 = announcementService.getAnnouncementList(1, 10);
            long time3 = System.currentTimeMillis() - start3;
            System.out.println("【测试】第三次查询耗时: " + time3 + "ms");
            
            System.out.println("========== 公告缓存测试结束 ==========\n");
            
            result.put("firstQueryTime", time1 + "ms");
            result.put("secondQueryTime", time2 + "ms");
            result.put("thirdQueryTime", time3 + "ms");
            result.put("cacheKeys", keys);
            result.put("recordCount", page1.getRecords().size());
            result.put("cacheWorking", time2 < time1 / 2); // 如果第二次查询时间小于第一次的一半，说明缓存生效
            
            return Result.success("公告缓存测试完成", result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("测试失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试4：手动测试序列化
     */
    @GetMapping("/test-serialization")
    public Result<Map<String, Object>> testSerialization() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            System.out.println("\n========== 测试序列化 ==========");
            
            // 查询一次数据
            IPage<Announcement> page = announcementService.getAnnouncementList(1, 10);
            
            // 尝试手动序列化并存入Redis
            String testKey = "test:announcement:manual";
            redisTemplate.opsForValue().set(testKey, page);
            System.out.println("【测试】手动写入缓存成功");
            
            // 尝试读取
            Object cachedPage = redisTemplate.opsForValue().get(testKey);
            System.out.println("【测试】手动读取缓存成功: " + (cachedPage != null));
            System.out.println("【测试】读取的数据类型: " + (cachedPage != null ? cachedPage.getClass().getName() : "null"));
            
            // 清理测试数据
            redisTemplate.delete(testKey);
            
            System.out.println("========== 序列化测试结束 ==========\n");
            
            result.put("serializationSuccess", true);
            result.put("deserializationSuccess", cachedPage != null);
            result.put("dataType", cachedPage != null ? cachedPage.getClass().getName() : "null");
            
            return Result.success("序列化测试完成", result);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("error", e.getMessage());
            result.put("errorType", e.getClass().getName());
            return Result.error("序列化测试失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试5：清空所有缓存
     */
    @DeleteMapping("/clear-all")
    public Result<String> clearAllCache() {
        try {
            Set<String> keys = redisTemplate.keys("*");
            if (keys != null && !keys.isEmpty()) {
                redisTemplate.delete(keys);
                return Result.success("已清空 " + keys.size() + " 个缓存key");
            }
            return Result.success("没有缓存需要清空");
        } catch (Exception e) {
            return Result.error("清空缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试6：检查CacheManager配置
     */
    @GetMapping("/cache-manager-info")
    public Result<Map<String, Object>> getCacheManagerInfo() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            result.put("cacheManagerClass", cacheManager.getClass().getName());
            result.put("cacheNames", cacheManager.getCacheNames());
            
            // 检查announcement缓存
            org.springframework.cache.Cache announcementCache = cacheManager.getCache("announcement");
            result.put("announcementCacheExists", announcementCache != null);
            if (announcementCache != null) {
                result.put("announcementCacheClass", announcementCache.getClass().getName());
            }
            
            return Result.success("CacheManager信息", result);
        } catch (Exception e) {
            return Result.error("获取CacheManager信息失败: " + e.getMessage());
        }
    }
}

